import json
import re

from django import http
from django.conf import settings
from django.contrib.auth import login
from django.shortcuts import render
from django.views import View

from QQLoginTool.QQtool import OAuthQQ
from django_redis import get_redis_connection

from apps.carts.utils import merge_cart_cookie_to_redis
from apps.oauth.models import OAuthQQUser

# 判断是否绑定openid
from apps.users.models import User
from meiduo_mall.utils.secret import SecretOauth


def is_bind_openid(request, openid):
    try:
        oauth_qq = OAuthQQUser.objects.get(openid=openid)
    except OAuthQQUser.DoesNotExist:
        # 没有绑定
        # 后端需要把加密的openid传递给绑定页面的前段
        access_token = SecretOauth().dumps({'openid':openid})
        return http.JsonResponse({'code':300, 'errmsg': '未绑定', 'access_token':access_token})

    else:
        # 绑定openid
        user = oauth_qq.user
        # 1,保持登录状态
        login(request, user)
        # 2,设置cookie,username
        response = http.JsonResponse({'code':0, 'errmsg':'成功'})
        response.set_cookie('username', user.username, max_age=3600*24*14)
        # 3,返回响应json code:0
        return response


class QQUserView(View):
    """用户扫码登录的回调处理"""
    """http://www.meiduo.site:8000/oauth_callback/
    ?code=AE263F12675FA79185B54870D79730A7&state=%2F"""
    def get(self, request):
        """ Oauth2.0 认证"""

        # 1.解析参数
        code = request.GET.get('code')
        # 2.校验
        if not code:
            return http.JsonResponse({'code': 400, 'errmsg': '缺少code'})

        # 3.美多 后台 认证 QQ 的身份
        oauth = OAuthQQ(
            client_id=settings.QQ_CLIENT_ID,
            client_secret=settings.QQ_CLIENT_SECRET,
            redirect_uri=settings.QQ_REDIRECT_URI,
            state=None
        )

        # 4. code-->token
        token = oauth.get_access_token(code)
        # 5. token-->openid
        openid = oauth.get_open_id(token)

        # 判断是否绑定openid
        response = is_bind_openid(request, openid)

        # 6.返回响应
        return response

    def post(self, request):
        """
        用户绑定到openid接口文档：
            路由：　　　　oauth_callback/
            请求方式：   post
            参数：json   mobile       string 必传　　手机号
                        password　　　string 必传　　密码
                        sms_code　　　string 必传　　短信验证码
                        access_token　string 必传　　openid

            响应结果:json   code和errmsg

        """
        # 1,接收参数，提取参数
        data_dict = json.loads(request.body.decode())
        mobile = data_dict.get('mobile')
        password = data_dict.get('password')
        sms_code = data_dict.get('sms_code')
        access_token = data_dict.get('access_token')
        # 2,校验参数
        if not all([mobile, password, sms_code, access_token]):
            return http.JsonResponse({'code':400, 'errmsg':'参数不齐'})
        if not re.match('1[3-9]\d{9}', mobile):
            return http.JsonResponse({'code':400, 'errmsg':'手机号格式不正确'})
        if not re.match(r'^[a-zA-Z0-9_-]{8,20}$', password):
            return http.JsonResponse({'code':400, 'errmsg':'密码格式不正确'})

        redis_conn = get_redis_connection('verify_code')
        sms_code_server = redis_conn.get('sms_%s' % mobile)
        # 校验前端和后台短信验证码
        if not sms_code_server:
            return http.JsonResponse({'code': 400, 'errmsg': '短信验证码过期了'})
        if sms_code != sms_code_server.decode():
            return http.JsonResponse({'code': 400, 'errmsg': '短信验证码有误'})

        # 3.判断openid是否有值
        openid = SecretOauth().loads(access_token).get('openid')
        if not openid:
            return http.JsonResponse({'code': 400, 'errmsg': 'openid为空'})

        # 4,判断mobile用户是否存在
        try:
            user = User.objects.get(mobile=mobile)
        except Exception as e:
            # 用户不存在
            print(e)
            user = User.objects.create_user(username=mobile, mobile=mobile, password=password)
        else:
            #　判断密码是否正确
            if not user.check_password(password):
                return http.JsonResponse({'code': 400, 'errmsg': '密码有误'})

        # 5,绑定openid入库
        try:
            OAuthQQUser.objects.create(user=user, openid=access_token)
        except Exception as e:
            print(e)

        # 6,保持登录状态
        login(request, user)

        # 7,设置cookie
        response = http.JsonResponse({'code': 0, 'errmsg': '绑定成功'})
        # 合并购物车
        merge_cart_cookie_to_redis(request=request, response=response)
        response.set_cookie('username', user.username, max_age=3600*24*14)

        # 8,返回响应json
        return response



class QQURLView(View):
    def get(self, request):
        # 1.美多 后台 认证 QQ 的身份
        oauth = OAuthQQ(
            client_id=settings.QQ_CLIENT_ID,
            client_secret=settings.QQ_CLIENT_SECRET,
            redirect_uri=settings.QQ_REDIRECT_URI,
            state=None
        )

        # 2.获取 qq 登录网址
        login_qq_url = oauth.get_qq_url()

        # 3.返回给前端 login_url
        return http.JsonResponse({'code': 0, 'errmsg': 'qq网址', 'login_url': login_qq_url})